From a442e6e8de796b655a948f4153c898aecec760da Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 1 Jul 2019 20:15:55 -0400 Subject: [PATCH] constraint editor: Use the list models Instead of handrolling our own list models, use the ones provided by GtkConstraintLayout. --- .../constraint-editor-window.c | 7 +- demos/constraint-editor/constraint-editor.c | 3 +- demos/constraint-editor/constraint-view.c | 240 ++++++++---------- demos/constraint-editor/guide-editor.c | 3 +- 4 files changed, 121 insertions(+), 132 deletions(-) diff --git a/demos/constraint-editor/constraint-editor-window.c b/demos/constraint-editor/constraint-editor-window.c index a8fa33464d..debbd7da51 100644 --- a/demos/constraint-editor/constraint-editor-window.c +++ b/demos/constraint-editor/constraint-editor-window.c @@ -295,13 +295,16 @@ create_widget_func (gpointer item, ConstraintEditorWindow *win = user_data; const char *name; GtkWidget *row, *box, *label, *button; + char *str; name = (const char *)g_object_get_data (G_OBJECT (item), "name"); row = gtk_list_box_row_new (); - g_object_set_data (G_OBJECT (row), "item", item); + g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - label = gtk_label_new (name); + str = g_strdup_printf ("%s %p", name, item); + label = gtk_label_new (str); + g_free (str); g_object_set (label, "margin", 10, NULL); diff --git a/demos/constraint-editor/constraint-editor.c b/demos/constraint-editor/constraint-editor.c index 5a85b35ecf..95d854ee9c 100644 --- a/demos/constraint-editor/constraint-editor.c +++ b/demos/constraint-editor/constraint-editor.c @@ -395,7 +395,8 @@ constraint_editor_constructed (GObject *object) double constant; nick = (char *)g_object_get_data (G_OBJECT (editor->constraint), "name"); - gtk_editable_set_text (GTK_EDITABLE (editor->name), nick); + if (nick) + gtk_editable_set_text (GTK_EDITABLE (editor->name), nick); target = gtk_constraint_get_target (editor->constraint); nick = get_target_name (target); diff --git a/demos/constraint-editor/constraint-view.c b/demos/constraint-editor/constraint-view.c index 7a4b094df5..8a050dbf8b 100644 --- a/demos/constraint-editor/constraint-view.c +++ b/demos/constraint-editor/constraint-view.c @@ -21,7 +21,7 @@ struct _ConstraintView { GtkWidget parent; - GListStore *store; + GListModel *model; GtkWidget *drag_widget; }; @@ -37,7 +37,7 @@ constraint_view_dispose (GObject *object) while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL) gtk_widget_unparent (child); - g_clear_object (&view->store); + g_clear_object (&view->model); G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object); } @@ -70,30 +70,38 @@ update_weak_position (ConstraintView *self, constraint); g_object_set_data (G_OBJECT (child), "x-constraint", NULL); } - constraint = gtk_constraint_new_constant (child, - GTK_CONSTRAINT_ATTRIBUTE_CENTER_X, - GTK_CONSTRAINT_RELATION_EQ, - x, - GTK_CONSTRAINT_STRENGTH_WEAK); - gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - g_object_set_data (G_OBJECT (child), "x-constraint", constraint); + if (x != -100) + { + constraint = gtk_constraint_new_constant (child, + GTK_CONSTRAINT_ATTRIBUTE_CENTER_X, + GTK_CONSTRAINT_RELATION_EQ, + x, + GTK_CONSTRAINT_STRENGTH_WEAK); + g_object_set_data (G_OBJECT (constraint), "internal", "yes"); + gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), + constraint); + g_object_set_data (G_OBJECT (child), "x-constraint", constraint); + } constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint"); if (constraint) { gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); + constraint); g_object_set_data (G_OBJECT (child), "y-constraint", NULL); } - constraint = gtk_constraint_new_constant (child, - GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y, - GTK_CONSTRAINT_RELATION_EQ, - y, - GTK_CONSTRAINT_STRENGTH_WEAK); - gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - g_object_set_data (G_OBJECT (child), "y-constraint", constraint); + if (y != -100) + { + constraint = gtk_constraint_new_constant (child, + GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y, + GTK_CONSTRAINT_RELATION_EQ, + y, + GTK_CONSTRAINT_STRENGTH_WEAK); + g_object_set_data (G_OBJECT (constraint), "internal", "yes"); + gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), + constraint); + g_object_set_data (G_OBJECT (child), "y-constraint", constraint); + } } static void @@ -141,15 +149,48 @@ drag_end (GtkGestureDrag *drag, self->drag_widget = NULL; } +static gboolean +omit_internal (gpointer item, gpointer user_data) +{ + if (g_object_get_data (G_OBJECT (item), "internal")) + return FALSE; + + return TRUE; +} + static void constraint_view_init (ConstraintView *self) { + GtkLayoutManager *manager; GtkEventController *controller; + GListStore *list; + GListModel *all_children; + GListModel *all_constraints; + GListModel *guides; + GListModel *children; + GListModel *constraints; + + manager = gtk_constraint_layout_new (); + gtk_widget_set_layout_manager (GTK_WIDGET (self), manager); + + all_children = gtk_widget_observe_children (GTK_WIDGET (self)); + all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager)); + guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager)); + constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL); + children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL); + + list = g_list_store_new (G_TYPE_LIST_MODEL); + g_list_store_append (list, children); + g_list_store_append (list, guides); + g_list_store_append (list, constraints); + self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list))); + g_object_unref (children); + g_object_unref (guides); + g_object_unref (constraints); + g_object_unref (all_children); + g_object_unref (all_constraints); + g_object_unref (list); - gtk_widget_set_layout_manager (GTK_WIDGET (self), - gtk_constraint_layout_new ()); - - self->store = g_list_store_new (G_TYPE_OBJECT); controller = (GtkEventController *)gtk_gesture_drag_new (); g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self); @@ -179,101 +220,66 @@ constraint_view_add_child (ConstraintView *view, gtk_widget_set_parent (frame, GTK_WIDGET (view)); update_weak_position (view, frame, 100, 100); - - g_list_store_append (view->store, frame); } void constraint_view_remove_child (ConstraintView *view, GtkWidget *child) { - int i; - + update_weak_position (view, child, -100, -100); gtk_widget_unparent (child); - - for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++) - { - if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)child) - { - g_list_store_remove (view->store, i); - break; - } - } } void constraint_view_add_guide (ConstraintView *view, GtkConstraintGuide *guide) { - GtkLayoutManager *manager; + GtkConstraintLayout *layout; GtkWidget *frame; GtkWidget *label; const char *name; GtkConstraint *constraint; + struct { + const char *name; + GtkConstraintAttribute attr; + } names[] = { + { "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT }, + { "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP }, + { "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH }, + { "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT }, + }; + int i; name = (const char *)g_object_get_data (G_OBJECT (guide), "name"); label = gtk_label_new (name); frame = gtk_frame_new (NULL); gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide"); - g_object_set_data_full (G_OBJECT (frame), "name", g_strdup (name), g_free); + g_object_set_data (G_OBJECT (frame), "internal", "yes"); gtk_container_add (GTK_CONTAINER (frame), label); gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL); g_object_set_data (G_OBJECT (guide), "frame", frame); g_object_set_data (G_OBJECT (guide), "label", label); - manager = gtk_widget_get_layout_manager (GTK_WIDGET (view)); - gtk_constraint_layout_add_guide (GTK_CONSTRAINT_LAYOUT (manager), - g_object_ref (guide)); - - constraint = gtk_constraint_new (frame, - GTK_CONSTRAINT_ATTRIBUTE_LEFT, - GTK_CONSTRAINT_RELATION_EQ, - guide, - GTK_CONSTRAINT_ATTRIBUTE_LEFT, - 1.0, 0.0, - GTK_CONSTRAINT_STRENGTH_REQUIRED); - gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - g_object_set_data (G_OBJECT (guide), "left-constraint", constraint); - - constraint = gtk_constraint_new (frame, - GTK_CONSTRAINT_ATTRIBUTE_TOP, - GTK_CONSTRAINT_RELATION_EQ, - guide, - GTK_CONSTRAINT_ATTRIBUTE_TOP, - 1.0, 0.0, - GTK_CONSTRAINT_STRENGTH_REQUIRED); - gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - g_object_set_data (G_OBJECT (guide), "top-constraint", constraint); - - constraint = gtk_constraint_new (frame, - GTK_CONSTRAINT_ATTRIBUTE_WIDTH, - GTK_CONSTRAINT_RELATION_EQ, - guide, - GTK_CONSTRAINT_ATTRIBUTE_WIDTH, - 1.0, 0.0, - GTK_CONSTRAINT_STRENGTH_REQUIRED); - gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - g_object_set_data (G_OBJECT (guide), "width-constraint", constraint); - - constraint = gtk_constraint_new (frame, - GTK_CONSTRAINT_ATTRIBUTE_HEIGHT, - GTK_CONSTRAINT_RELATION_EQ, - guide, - GTK_CONSTRAINT_ATTRIBUTE_HEIGHT, - 1.0, 0.0, - GTK_CONSTRAINT_STRENGTH_REQUIRED); - gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - g_object_set_data (G_OBJECT (guide), "height-constraint", constraint); + layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view))); + gtk_constraint_layout_add_guide (layout, g_object_ref (guide)); - update_weak_position (view, frame, 150, 150); + for (i = 0; i < G_N_ELEMENTS (names); i++) + { + constraint = gtk_constraint_new (frame, + names[i].attr, + GTK_CONSTRAINT_RELATION_EQ, + guide, + names[i].attr, + 1.0, 0.0, + GTK_CONSTRAINT_STRENGTH_REQUIRED); + g_object_set_data (G_OBJECT (constraint), "internal", "yes"); + gtk_constraint_layout_add_constraint (layout, constraint); + g_object_set_data (G_OBJECT (guide), names[i].name, constraint); + } - g_list_store_append (view->store, guide); + update_weak_position (view, frame, 150, 150); } void @@ -287,12 +293,11 @@ constraint_view_guide_changed (ConstraintView *view, name = (const char *)g_object_get_data (G_OBJECT (guide), "name"); label = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "label"); gtk_label_set_label (GTK_LABEL (label), name); - - for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++) + for (i = 0; i < g_list_model_get_n_items (view->model); i++) { - if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)guide) + if (g_list_model_get_item (view->model, i) == (GObject*)guide) { - g_list_model_items_changed (G_LIST_MODEL (view->store), i, 1, 1); + g_list_model_items_changed (view->model, i, 1, 1); break; } } @@ -302,40 +307,30 @@ void constraint_view_remove_guide (ConstraintView *view, GtkConstraintGuide *guide) { - GtkLayoutManager *manager; + GtkConstraintLayout *layout; GtkWidget *frame; GtkConstraint *constraint; + const char *names[] = { + "left-constraint", + "top-constraint", + "width-constraint", + "height-constraint" + }; int i; - manager = gtk_widget_get_layout_manager (GTK_WIDGET (view)); + layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view))); - constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "left-constraint"); - gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "top-constraint"); - gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "width-constraint"); - gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); - constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), "height-constraint"); - gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager), - constraint); + for (i = 0; i < G_N_ELEMENTS (names); i++) + { + constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]); + gtk_constraint_layout_remove_constraint (layout, constraint); + } frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame"); + update_weak_position (view, frame, -100, -100); gtk_widget_unparent (frame); - gtk_constraint_layout_remove_guide (GTK_CONSTRAINT_LAYOUT (manager), - guide); - - for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++) - { - if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)guide) - { - g_list_store_remove (view->store, i); - break; - } - } + gtk_constraint_layout_remove_guide (layout, guide); } void @@ -347,8 +342,6 @@ constraint_view_add_constraint (ConstraintView *view, manager = gtk_widget_get_layout_manager (GTK_WIDGET (view)); gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager), g_object_ref (constraint)); - - g_list_store_append (view->store, constraint); } void @@ -356,23 +349,14 @@ constraint_view_remove_constraint (ConstraintView *view, GtkConstraint *constraint) { GtkLayoutManager *manager; - int i; manager = gtk_widget_get_layout_manager (GTK_WIDGET (view)); gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager), constraint); - for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (view->store)); i++) - { - if (g_list_model_get_item (G_LIST_MODEL (view->store), i) == (GObject*)constraint) - { - g_list_store_remove (view->store, i); - break; - } - } } GListModel * constraint_view_get_model (ConstraintView *view) { - return G_LIST_MODEL (view->store); + return view->model; } diff --git a/demos/constraint-editor/guide-editor.c b/demos/constraint-editor/guide-editor.c index 39bd08a157..947274f2ad 100644 --- a/demos/constraint-editor/guide-editor.c +++ b/demos/constraint-editor/guide-editor.c @@ -239,7 +239,8 @@ guide_editor_constructed (GObject *object) int w, h; nick = (char *)g_object_get_data (G_OBJECT (editor->guide), "name"); - gtk_editable_set_text (GTK_EDITABLE (editor->name), nick); + if (nick) + gtk_editable_set_text (GTK_EDITABLE (editor->name), nick); gtk_constraint_guide_get_min_size (editor->guide, &w, &h); gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w); -- 2.30.2